//
//  SelectPhotoManager.swift
//  selectPhoto
//
//  Created by 孟祥群 on 2018/4/24.
//  Copyright © 2018年 孟祥群. All rights reserved.
//

import UIKit
import Photos
import MobileCoreServices
typealias selectBlock = (_ imageArr:Array<UIImage>)->()
typealias selectAssetPathBlock = (_ imageArr:Array<String>)->()

class SelectPhotoManager: NSObject, PhotoPickerControllerDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    /// 选择图片回调
    var selectBlock:selectBlock?
    /// 选择图片路径回调
    var selectPathBlock:selectAssetPathBlock?
    var controller:UIViewController?
    /// 最大图片数量
    var largestNum:Int = 0
    /// 已选择数量
    var haveNum:Int = 0
    let imageSize: CGFloat = 300
    var localId:String?
    static let manager = SelectPhotoManager()
    
    @objc func selectPhoto(dataSource:UIViewController, maximum:Int, haveNb:Int, selectBlock:@escaping selectBlock) -> Void {
        controller = dataSource
        largestNum = maximum
        haveNum = haveNb
        self.selectBlock = selectBlock
        self.eventAddImage()
    }
    @objc func selectPhotoPaths(dataSource:UIViewController, maximum:Int, haveNb:Int, selectPathBlock:@escaping selectAssetPathBlock) -> Void {
      controller = dataSource
      largestNum = maximum
      haveNum = haveNb
      self.selectPathBlock = selectPathBlock
      self.eventAddImage()
    }
    
    func eventAddImage() {
        let alert = UIAlertController.init(title: nil, message: nil, preferredStyle: .actionSheet)
        
        // change the style sheet text color
        alert.view.tintColor = UIColor(hexStr: "#007AFF", alpha: 1.0)
        
        let actionCancel = UIAlertAction.init(title: "取消", style: .cancel, handler: nil)
        let actionCamera = UIAlertAction.init(title: "拍照", style: .default) { (UIAlertAction) -> Void in
            self.selectByCamera()
        }

        let actionPhoto = UIAlertAction.init(title: "从相册选择上传", style: .default) { (UIAlertAction) -> Void in
            self.selectFromPhoto()
        }
        alert.addAction(actionCancel)
        alert.addAction(actionCamera)
        alert.addAction(actionPhoto)
        
        controller?.present(alert, animated: true, completion: nil)
    }
    // 拍照获取
    private func selectByCamera(){
        if UIImagePickerController.isSourceTypeAvailable(.camera) {
            
            let imagePicker = UIImagePickerController()
            imagePicker.sourceType = .camera // 调用摄像头
            imagePicker.cameraCaptureMode = .photo // 拍照
            if UIImagePickerController.isCameraDeviceAvailable(.rear) {
                
                imagePicker.cameraDevice = .rear // 后置摄像头拍照
            }
            imagePicker.allowsEditing = false
            imagePicker.delegate = self
            imagePicker.mediaTypes = [kUTTypeImage as String]
            
            imagePicker.modalPresentationStyle = .popover
            controller?.show(imagePicker, sender: nil)
        }
    }
    
    // MARK: -  拍照 delegate相关方法
    // 退出拍照
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        picker.dismiss(animated: true, completion: nil)
    }
    
    
    // 完成拍照
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        
        picker.dismiss(animated: true, completion: nil)
        let mediaType = info[UIImagePickerController.InfoKey.mediaType] as! String;
        var image: UIImage? = nil
        if picker.isEditing { // 拍照图片运行编辑，则优先尝试从编辑后的类型中获取图片
          image = info[UIImagePickerController.InfoKey.editedImage] as? UIImage
        }else{
          image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
        }
        guard let photoImage = image else { return }
      
        if let tempSelectBlock = selectBlock {
          if mediaType == kUTTypeImage as String { // 图片类型
            tempSelectBlock([photoImage])
          }
        }else if let tempSelectPathBlock = selectPathBlock {
          PHPhotoLibrary.shared().performChanges({
            let result = PHAssetChangeRequest.creationRequestForAsset(from: photoImage)
            let assetPlaceholder = result.placeholderForCreatedAsset
            self.localId = assetPlaceholder?.localIdentifier
          }) { (isSuccess, error) in
            if isSuccess {
              //通过标志符获取对应的资源
              let assetResult = PHAsset.fetchAssets(
                withLocalIdentifiers: [self.localId ?? ""], options: nil)
              let asset = assetResult[0]
              let options = PHContentEditingInputRequestOptions()
              options.canHandleAdjustmentData = {(adjustmeta: PHAdjustmentData)
                -> Bool in
                return true
              }
              //获取保存的图片路径
              asset.requestContentEditingInput(with: options, completionHandler: {
                (contentEditingInput:PHContentEditingInput?, info: [AnyHashable : Any]) in
                if let imagePath = contentEditingInput?.fullSizeImageURL?.absoluteString {
                  tempSelectPathBlock([imagePath])
                }
              })
            }
          }
        }
    }
    
    /**
     * 从相册中选择图片
     */
    private func selectFromPhoto(){
        PHPhotoLibrary.requestAuthorization {[unowned self] (status) -> Void in
            DispatchQueue.main.async {
                switch status {
                case .authorized:
                    self.showLocalPhotoGallery()
                    break
                default:
                    self.showNoPermissionDailog()
                    break
                }
            }
        }
    }
    /**
     * 用户相册未授权，Dialog提示
     */
    private func showNoPermissionDailog(){
        let alert = UIAlertController.init(title: nil, message: "没有打开相册的权限", preferredStyle: .alert)
        alert.addAction(UIAlertAction.init(title: "确定", style: .default, handler: nil))
        controller?.present(alert, animated: true, completion: nil)
    }
    
    /**
     * 打开本地相册列表
     */
    private func showLocalPhotoGallery(){
        let picker = PhotoPickController(type: PageType.AllAlbum)
        picker.imageSelectDelegate = self
        picker.modalPresentationStyle = .popover
        PhotoPickController.imageMaxSelectedNum = largestNum // 允许选择的最大图片张数
        PhotoPickController.alreadySelectedImageNum = haveNum
        controller?.show(picker, sender: nil)
    }
    
    func onImageSelectFinished(images: [PHAsset]) {
        if let tempSelectBlock = selectBlock {
            var imageArr:Array<UIImage> = [UIImage]()
            for item in images {
              let image = self.getAssetThumbnail(asset: item)
              imageArr.append(image)
            }
            PhotoImage.instance.selectedImage.removeAll()
            tempSelectBlock(imageArr)
        }else if let tempSelectPathBlock = selectPathBlock {
            var imagePathArr:[String] = []
            var remainCount = images.count
            images.forEach { (asset) in
              asset.requestContentEditingInput(with: nil, completionHandler: { (contentEditingInput, info) in
                if let path = contentEditingInput?.fullSizeImageURL?.absoluteString {
                  imagePathArr.append(path)
                }
                remainCount -= 1
                if remainCount <= 0 {
                  PhotoImage.instance.selectedImage.removeAll()
                  tempSelectPathBlock(imagePathArr)
                }
              })
            }
        }
    }
    
    func getAssetThumbnail(asset: PHAsset) -> UIImage {
        let retinaScale = UIScreen.main.scale
        let retinaSquare = CGSize(width: imageSize * retinaScale, height: imageSize * retinaScale)
        let cropSizeLength = min(asset.pixelWidth, asset.pixelHeight)
        let square = CGRect(x:0, y: 0,width: CGFloat(cropSizeLength),height: CGFloat(cropSizeLength))
        let cropRect = square.applying(CGAffineTransform(scaleX: 1.0/CGFloat(asset.pixelWidth), y: 1.0/CGFloat(asset.pixelHeight)))
        
        let manager = PHImageManager.default()
        let options = PHImageRequestOptions()
        var thumbnail = UIImage()
        options.isNetworkAccessAllowed = true
        options.isSynchronous = true
        options.deliveryMode = .highQualityFormat
        options.resizeMode = .none
        options.normalizedCropRect = cropRect
        var isPhotoInICloud = false
        options.progressHandler = { (progress,error,stop,info) in
            isPhotoInICloud = true
        }
        
        manager.requestImage(for: asset, targetSize: retinaSquare, contentMode: .aspectFit, options: options, resultHandler: {(result, info)->Void in
            if isPhotoInICloud {
            if result != nil {
            thumbnail = result!
            }
            }else {
                if result != nil {
                    thumbnail = result!
                }
            }
        })
        return thumbnail
    }
    
}

extension SelectPhotoManager {
    @objc public static func sharedInstance() -> SelectPhotoManager{
      return manager;
    }
}
